<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Polymorphism and return values of functions
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora017.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora019.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Polymorphism and return values of functions</H2>
<A NAME="sec-retourpoly"></A>
Objective CAML's parametric polymorphism permits the definition of
functions whose return type is completely unspecified. For example:


<PRE><BR># <B>let</B><CODE> </CODE>id<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val id : 'a -&gt; 'a = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
However, the return type depends on the type of the argument. Thus, when
the function <TT>id</TT> is applied to an argument, the type inference
mechanism knows how to instantiate the type variable <I>'a</I>. So for
each particular use, the type of <TT>id</TT> can be determined.<BR>
<BR>
If this were not so, it would no longer make sense to use strong static
typing, entrusted with ensuring execution safety. Indeed, a function of
completely unspecified type such as <I>'a -&gt; 'b</I> would allow any type
conversion whatsoever, which would inevitably lead to a run-time error
since the physical representations of values of different types are not the
same. <BR>
<BR>

<H4> Apparent contradiction</H4>
However, it is possible in the Objective CAML language to define a function whose
return type contains a type variable which does not appear in the types of
its arguments. We will consider several such examples and see why such a
possibility is not contradictory to strong static typing.<BR>
<BR>
Here is a first example:


<PRE><BR># <B>let</B><CODE> </CODE>f<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>[]<CODE> </CODE>;;<BR><CODE>val f : 'a -&gt; 'b list = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
This function lets us construct a polymorphic value from anything at all:


<PRE><BR># f<CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>- : '_a list = []</CODE><BR># f<CODE> </CODE><CODE>"anything at all"</CODE><CODE> </CODE>;;<BR><CODE>- : '_a list = []</CODE><BR>

</PRE>
<BR>
<BR>
Nevertheless, the value obtained isn't entirely unspecified: we're dealing
with a list. So it can't be used just anywhere.<BR>
<BR>
Here are three examples whose type is the dreaded <I>'a -&gt; 'b</I>:


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>f1<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>f1<CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val f1 : 'a -&gt; 'b = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>f2<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>failwith<CODE> </CODE><CODE>"anything at all"</CODE><CODE> </CODE>;;<BR><CODE>val f2 : 'a -&gt; 'b = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>f3<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>List.hd<CODE> </CODE>[]<CODE> </CODE>;;<BR><CODE>val f3 : 'a -&gt; 'b = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
These functions are not, in fact, dangerous vis-a-vis execution safety,
since it isn't possible to use them to construct a value: the first one loops forever, the
latter two raise an exception which interrupts the computation.<BR>
<BR>
Similarly, it is in order to prevent functions of type
<I>'a -&gt; 'b</I> from being defined that new exception constructors are
forbidden from having arguments whose type contains a variable.<BR>
<BR>
Indeed, if one could declare a polymorphic exception
<TT>Poly_exn</TT> of type <I>'a -&gt; exn</I>, one could then write the
function:


<PRE><BR><B>let</B><CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE>raise<CODE> </CODE><TT>(</TT>Poly_exn<CODE> </CODE><B>false</B><TT>)</TT><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>n<CODE> </CODE>-&gt;<CODE> </CODE>n<CODE>+</CODE><CODE>1</CODE><CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
The function <TT>f</TT> being of type <I>int -&gt; int</I> and
<TT>Poly_exn</TT> being of type <I>'a -&gt; exn</I>, one could then define:


<PRE><BR><B>let</B><CODE> </CODE>g<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>try</B><CODE> </CODE>f<CODE> </CODE>n<CODE> </CODE><B>with</B><CODE> </CODE>Poly_exn<CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE>+</CODE><CODE>1</CODE><CODE> </CODE>;;<BR>

</PRE>

This function is equally well-typed (since the argument of
<TT>Poly_exn</TT> may be arbitrary) and now, evaluation of <TT>(g 0)</TT>
would end up in an attempt to add an integer and a boolean!<BR>
<BR>
<BR>
<BR>
<HR>
<A HREF="book-ora017.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora019.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
